--[[-------------------------------------------------------------------------
  Copyright (c) 2006, Jim Whitehead II <cladhaire@gmail.com>
  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are
  met:

      * Redistributions of source code must retain the above copyright
        notice, this list of conditions and the following disclaimer.
      * Redistributions in binary form must reproduce the above
        copyright notice, this list of conditions and the following
        disclaimer in the documentation and/or other materials provided
        with the distribution.
      * Neither the name of PerfectRaid nor the names of its contributors 
        may be used to endorse or promote products derived from this software
        without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------]]

local utils = DongleStub("DongleUtils")

function PerfectRaid:SkinFrame(frame)
	local topleft = frame:CreateTexture()
	topleft:SetHeight(32) topleft:SetWidth(32)
	topleft:SetPoint("TOPLEFT", 0, 0)
	topleft:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\TopLeft")

	local topright = frame:CreateTexture()
	topright:SetHeight(32) topright:SetWidth(32)
	topright:SetPoint("TOPRIGHT", 0, 0)
	topright:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\TopRight")

	local botleft = frame:CreateTexture()
	botleft:SetHeight(32) botleft:SetWidth(32)
	botleft:SetPoint("BOTTOMLEFT", 0, 0)
	botleft:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\BotLeft")

	local botright = frame:CreateTexture()
	botright:SetHeight(32) botright:SetWidth(32)
	botright:SetPoint("BOTTOMRIGHT", 0, 0)
	botright:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\BotRight")

	local top = frame:CreateTexture()
	top:SetPoint("TOPLEFT", 32, 0)
	top:SetPoint("TOPRIGHT", -32, 0)
	top:SetHeight(32)
	top:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\Top")

	local left = frame:CreateTexture()
	left:SetPoint("TOPLEFT", 0, -32)
	left:SetPoint("BOTTOMLEFT", 0, 32)
	left:SetWidth(32)
	left:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\Left")

	local right = frame:CreateTexture()
	right:SetPoint("TOPRIGHT", 0, -32)
	right:SetPoint("BOTTOMRIGHT", 0, 32)
	right:SetWidth(32)
	right:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\Right")

	local bot = frame:CreateTexture()
	bot:SetPoint("BOTTOMLEFT", 32, 0)
	bot:SetPoint("BOTTOMRIGHT", -32, 0)
	bot:SetHeight(32)
	bot:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\Bot")

	local titlebar = frame:CreateTitleRegion()
	titlebar:SetPoint("TOPRIGHT", -6, -6)
	titlebar:SetPoint("TOPLEFT", 5, -6)
	titlebar:SetHeight(32)

	frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
	frame.title:SetPoint("CENTER", titlebar, "CENTER", 0, 8)

	local titletopright = frame:CreateTexture()
	titletopright:SetHeight(32) titletopright:SetWidth(64)
	titletopright:SetPoint("TOPRIGHT", titlebar, "TOPRIGHT", 0, 0)
	titletopright:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\TitleTopRight")

	local titletop = frame:CreateTexture()
	titletop:SetPoint("TOPLEFT", titlebar, "TOPLEFT", 0, 0)
	titletop:SetPoint("TOPRIGHT", titletopright, "TOPLEFT", 0, 0)
	titletop:SetHeight(32)
	titletop:SetTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\TitleTop")

	local backdrop = frame:CreateTexture(nil, "BACKGROUND")
	backdrop:SetAllPoints()
	backdrop:SetTexture(0,0,0,1)

	local close = CreateFrame("Button", nil, frame)
	close:SetHeight(32) close:SetWidth(32)
	close:SetPoint("BOTTOMRIGHT", titletopright, "BOTTOMRIGHT", 0, 0)
	close:SetNormalTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\Close")
	close:SetHighlightTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\CloseDown")
	close:GetHighlightTexture():SetBlendMode("BLEND")
	close:SetScript("OnClick", function() frame:Hide() end)
	close:SetHitRectInsets(15, 3, 2, 15)

	local resize = CreateFrame("Button", nil, frame)
	resize:SetHeight(5)
	resize:SetWidth(5)
	resize:SetPoint("BOTTOMRIGHT", 0, 0)
	resize:SetScript("OnMouseDown", function() pcall(frame.StartSizing, frame) end)
	resize:SetScript("OnMouseUp", function() pcall(frame.StopMovingOrSizing, frame) end)

	frame:EnableMouse(true)
	frame:SetMovable(true)
	frame:SetResizable(true)
end

function PerfectRaid:SkinButton(button)
	button:SetHeight(24)
	button:SetWidth(75)
	button:SetNormalTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\ButtonNormal")
	button:SetHighlightTexture("Interface\\AddOns\\PerfectRaid\\images\\theme\\ButtonHighlight")
	button.text = button:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
	button.text:SetPoint("CENTER", 0, 0)
	button.text:SetJustifyH("CENTER")
end

function PerfectRaid:CreateOptions()
	local frame = CreateFrame("Frame", "PROptions")
	frame:SetHeight(250)
	frame:SetWidth(350)
	frame:SetPoint("CENTER", 0, 0)
	self:SkinFrame(frame)
	frame.title:SetText("PerfectRaid Configuration")

	self.editMode = "Frames"
	frame:SetScript("OnHide", function() PREditRaid:Hide() end)

	local function MakeEntry(name, parent)
		local entry = CreateFrame("CheckButton", name, parent)
		entry:SetHeight(30)
		entry:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
		entry:SetCheckedTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
		entry:GetHighlightTexture():SetBlendMode("ADD")
		entry.line1 = entry:CreateFontString(nil, "ARTWORK", "GameFontNormal")
		entry.line1:SetPoint("TOPLEFT", 0 ,0)
		entry.line1:SetPoint("RIGHT", -5, 0)
		entry.line1:SetText("Example Group Header")
		entry.line1:SetJustifyH("LEFT")
		entry.line2 = entry:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
		entry.line2:SetPoint("TOPLEFT", entry.line1, "BOTTOMLEFT", 0, 0)
		entry.line2:SetPoint("RIGHT", -5, 0)
		entry.line2:SetText("Warrior, Rogue, Group 1, Warlock")
		entry.line2:SetJustifyH("LEFT")
		return entry
	end

	local entry1 = MakeEntry("PROptionsEntry1", frame)
	entry1:SetPoint("TOPLEFT", 15, -30)
	entry1:SetPoint("RIGHT", 0, 0)
	entry1.idx = 1

	local entry2 = MakeEntry("PROptionsEntry1", frame)
	entry2:SetPoint("TOPLEFT", entry1, "BOTTOMLEFT", 0, 0)
	entry2:SetPoint("RIGHT", 0, 0)
	entry2.idx = 2

	local entry3 = MakeEntry("PROptionsEntry1", frame)
	entry3:SetPoint("TOPLEFT", entry2, "BOTTOMLEFT", 0, 0)
	entry3:SetPoint("RIGHT", 0, 0)
	entry3.idx = 3

	local entry4 = MakeEntry("PROptionsEntry1", frame)
	entry4:SetPoint("TOPLEFT", entry3, "BOTTOMLEFT", 0, 0)
	entry4:SetPoint("RIGHT", 0, 0)
	entry4.idx = 4

	local entry5 = MakeEntry("PROptionsEntry1", frame)
	entry5:SetPoint("TOPLEFT", entry4, "BOTTOMLEFT", 0, 0)
	entry5:SetPoint("RIGHT", 0, 0)
	entry5.idx = 5

	local entry6 = MakeEntry("PROptionsEntry1", frame)
	entry6:SetPoint("TOPLEFT", entry5, "BOTTOMLEFT", 0, 0)
	entry6:SetPoint("RIGHT", 0, 0)
	entry6.idx = 6

	local entries = {entry1, entry2, entry3, entry4, entry5, entry6}
	local selected = nil
	
	local button1 = CreateFrame("Button", "PRButtonAdd", frame)
	self:SkinButton(button1)
	button1.text:SetText("Add")
	button1:SetPoint("BOTTOMLEFT", 10, 10)

	local button2 = CreateFrame("Button", "PRButtonEdit", frame)
	self:SkinButton(button2)
	button2.text:SetText("Edit")
	button2:SetPoint("LEFT", button1, "RIGHT", 8, 0)

	local button5 = CreateFrame("Button", "PRButtonDelete", frame)
	self:SkinButton(button5)
	button5.text:SetText("Delete")
	button5:SetPoint("LEFT", button2, "RIGHT", 8, 0)

	local button6 = CreateFrame("Button", "PRButtonMode", frame)
	self:SkinButton(button6)
	button6.text:SetText("Edit Buffs")
	button6:SetPoint("LEFT", button5, "RIGHT", 8, 0)

	local scrollframe = CreateFrame("ScrollFrame", "PRScrollFrame", frame, "FauxScrollFrameTemplate")
	scrollframe:SetPoint("TOPLEFT", entry1, "TOPLEFT", 0, 0)
	scrollframe:SetPoint("BOTTOMRIGHT", entry6, "BOTTOMRIGHT", 0, 0)

	local texture = scrollframe:CreateTexture(nil, "BACKGROUND")
	texture:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
	texture:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 14, 0)
	texture:SetPoint("BOTTOMRIGHT", scrollframe, "BOTTOMRIGHT", 23, 0)
	texture:SetGradientAlpha("HORIZONTAL", 0.5, 0.25, 0.05, 0, 0.15,0.15, 0.15, 1)

	local texture = scrollframe:CreateTexture(nil, "BACKGROUND")
	texture:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
	texture:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, 0)
	texture:SetPoint("BOTTOMRIGHT", scrollframe, "BOTTOMRIGHT", 14, 0)
	texture:SetGradientAlpha("HORIZONTAL", 0.15, 0.15, 0.15, 0.15, 1, 0.5, 0.25, 0.05, 0)

	local update = function()
		local list
		if self.editMode == "Frames" then
			list = self.db.profile.headers
		elseif self.editMode == "Buffs" then
			list = self.db.profile.buffs
		end

		local idx,button
		local offset = FauxScrollFrame_GetOffset(scrollframe)
		FauxScrollFrame_Update(scrollframe, #list, 6, 30)
		for i=1,6 do
			idx = offset + i
			button = entries[i]
			if idx <= #list then
				local entry = list[idx]
				button.line1:SetText(entry.name)
				button.line2:SetText(entry.desc)
				button:Show()
				if selected == button then
					button:SetChecked(true)
				else
					button:SetChecked(false)
				end
			else
				button:Hide()
			end
		end

		if selected then
			PRButtonEdit:Enable()
			PRButtonEdit.text:SetText(PRButtonEdit.oldText)
			PRButtonDelete:Enable()
			PRButtonDelete.text:SetText(PRButtonDelete.oldText)
		else
			PRButtonEdit:Disable()
			local text = PRButtonEdit.text:GetText()
			PRButtonEdit.oldText = PRButtonEdit.oldText or text
			PRButtonEdit.text:SetText("|cFF444444" .. text .. "|r")
			PRButtonDelete:Disable()
			local text = PRButtonDelete.text:GetText()
			PRButtonDelete.oldText = PRButtonDelete.oldText or text
			PRButtonDelete.text:SetText("|cFF444444" .. text .. "|r")
		end
	end

	local postclick = function(frame)
		for idx,entry in pairs(entries) do
			if entry == frame then
				entry:SetChecked(true)
				selected = entry
			else
				entry:SetChecked(false)
			end
		end
		update()
	end
	for idx,frame in pairs(entries) do
		frame:SetScript("PostClick", postclick)
	end

	scrollframe.update = update
	scrollframe:SetScript("OnShow", update)

	scrollframe:SetScript("OnVerticalScroll", function()
		FauxScrollFrame_OnVerticalScroll(30, update)
	end)

	update()

	-- End main options window

	local frame = CreateFrame("Frame", "PREditRaid")
	frame:SetFrameStrata("HIGH")
	frame:SetHeight(400)
	frame:SetWidth(350)
	frame:SetPoint("CENTER", 75, -25)
	self:SkinFrame(frame)
	frame:Hide()
	frame.title:SetText("Add a raid group")
	frame:SetScript("OnHide", function() PRButtonRaidCancel:Click() end)

	button1:SetScript("OnClick", function()
		if self.editMode == "Frames" then
			PREditRaid:Show()
		elseif self.editMode == "Buffs" then
			PREditBuff:Show()
		end
	end)

	local edit1 = CreateFrame("EditBox", nil, frame, "InputBoxTemplate")
	edit1:SetPoint("TOPLEFT", 75, -35)
	edit1:SetWidth(200)
	edit1:SetHeight(25)
	edit1:SetAutoFocus(false)
	edit1.label = edit1:CreateFontString(nil, nil, "GameFontHighlightSmall")
	edit1.label:SetPoint("RIGHT", edit1, "LEFT", -10, 0)
	edit1.label:SetJustifyH("RIGHT")
	edit1.label:SetText("Name:")

	frame:SetScript("OnShow", function() edit1:SetFocus() end)

	local classes = {
		"Druid",
		"Hunter",
		"Mage",
		"Paladin",
		"Priest",
		"Rogue",
		"Shaman",
		"Warlock",
		"Warrior",
	}

	local groups = {
		"Group 1",
		"Group 2",
		"Group 3",
		"Group 4",
		"Group 5",
		"Group 6",
		"Group 7",
		"Group 8",
	}

	local label1 = frame:CreateFontString(nil, nil, "GameFontHighlightSmall")
	label1:SetPoint("TOPLEFT", edit1.label, "BOTTOMLEFT", 0, -15)
	label1:SetText("Include these classes:")

	local boxes = {}

	for i=1,#classes do
		local box = CreateFrame("CheckButton", "Check"..i, frame, "UICheckButtonTemplate")
		box.text = getglobal(box:GetName().."Text")
		box.label = classes[i]
		box.text:SetText(classes[i])
		box.value = string.upper(classes[i])
		boxes[i] = box
	end

	boxes[1]:SetPoint("TOPLEFT", label1, "BOTTOMLEFT", 0, 0)
	boxes[2]:SetPoint("LEFT", boxes[1], "LEFT", 100, 0)
	boxes[3]:SetPoint("LEFT", boxes[2], "LEFT", 100, 0)

	boxes[4]:SetPoint("TOPLEFT", boxes[1], "BOTTOMLEFT", 0, 0)
	boxes[5]:SetPoint("LEFT", boxes[4], "LEFT", 100, 0)
	boxes[6]:SetPoint("LEFT", boxes[5], "LEFT", 100, 0)

	boxes[7]:SetPoint("TOPLEFT", boxes[4], "BOTTOMLEFT", 0, 0)
	boxes[8]:SetPoint("LEFT", boxes[7], "LEFT", 100, 0)
	boxes[9]:SetPoint("LEFT", boxes[8], "LEFT", 100, 0)

	local label2 = frame:CreateFontString(nil, nil, "GameFontHighlightSmall")
	label2:SetPoint("TOPLEFT", boxes[7], "BOTTOMLEFT", 0, -15)
	label2:SetText("Include these raid groups:")

	for i=1,#groups do
		local box = CreateFrame("CheckButton", "Check"..9+i, frame, "UICheckButtonTemplate")
		box.text = getglobal(box:GetName().."Text")
		box.label = groups[i]
		box.text:SetText(groups[i])
		box.value = tonumber(string.sub(groups[i], -1, -1))
		boxes[9+i] = box
	end

	boxes[10]:SetPoint("TOPLEFT", label2, "BOTTOMLEFT", 0, 0)
	boxes[11]:SetPoint("LEFT", boxes[10], "LEFT", 100, 0)
	boxes[12]:SetPoint("LEFT", boxes[11], "LEFT", 100, 0)

	boxes[13]:SetPoint("TOPLEFT", boxes[10], "BOTTOMLEFT", 0, 0)
	boxes[14]:SetPoint("LEFT", boxes[13], "LEFT", 100, 0)
	boxes[15]:SetPoint("LEFT", boxes[14], "LEFT", 100, 0)

	boxes[16]:SetPoint("TOPLEFT", boxes[13], "BOTTOMLEFT", 0, 0)
	boxes[17]:SetPoint("LEFT", boxes[16], "LEFT", 100, 0)

	local label3 = frame:CreateFontString(nil, nil, "GameFontHighlightSmall")
	label3:SetPoint("TOPLEFT", boxes[16], "BOTTOMLEFT", 0, -15)
	label3:SetText("Options:")

	local box = CreateFrame("CheckButton", "Check18", frame, "UICheckButtonTemplate")
	box:SetPoint("TOPLEFT", label3, "BOTTOMLEFT", 0, 0)
	box.text = getglobal(box:GetName().."Text")
	box.text:SetText("Strict Filtering\n(must match both group and class)")
	box.text:SetJustifyH("LEFT")
	boxes[18] = box
	boxes[18].label = "(Strict)"
	boxes[18].value = "strict"

	local button3 = CreateFrame("Button", "PRButtonRaidSave", frame)
	self:SkinButton(button3)
	button3.text:SetText("Save")
	button3:SetPoint("CENTER", frame, "BOTTOM", -40, 25)

	local button4 = CreateFrame("Button", "PRButtonRaidCancel", frame)
	self:SkinButton(button4)
	button4.text:SetText("Cancel")
	button4:SetPoint("CENTER", frame, "BOTTOM", 40, 25)

	button3:SetScript("OnClick", function()
		local edit = self.editSave
		local entry = edit or {}
		entry.name = edit1:GetText()
		if entry.name == "" then entry.name = "Unnamed" end

		local work = {}
		local filters = {}
		for i=1,#boxes do
			if boxes[i]:GetChecked() then
				table.insert(work, boxes[i].label)
				table.insert(filters, boxes[i].value)
			end
		end

		entry.strict = Check18:GetChecked()
		entry.desc = strjoin(", ", unpack(work))
		entry.filters = filters
		if not edit then
			table.insert(self.db.profile.headers, entry)
		end
		button4:Click()
		scrollframe.update()
		self:CreateRaidHeaders()
	end)
		
	button4:SetScript("OnClick", function()
		for i=1,#boxes do
			boxes[i]:SetChecked(nil)
		end
		edit1:SetText("")
		self.editSave = nil
		frame:Hide()
	end)

	button2:SetScript("OnClick", function()
		local list,frame,checklist

		if self.editMode == "Frames" then
			list = self.db.profile.headers
			frame = PREditRaid
			checklist = "filters"
		elseif self.editMode == "Buffs" then
			list = self.db.profile.buffs
			frame = PREditBuff
			checklist = "cond"
		end

		local idx = selected.idx
		local offset = FauxScrollFrame_GetOffset(scrollframe)
		local entry = list[offset + idx]
		self.editSave = entry

		boxes = frame.boxes

		for i,box in ipairs(boxes) do
			for k,v in pairs(entry[checklist]) do
				if box.value == v then
					box:SetChecked()
				end
			end
		end

		if self.editMode == "Frames" then
			edit1:SetText(entry.name)			
		elseif self.editMode == "Buffs" then
			PREditBuffName:SetText(entry.buffname or "")
			PREditGroupName:SetText(entry.groupbuff or "")
			PREditDispText:SetText(entry.disptext or "")
			PRIconButton.icon:SetTexture(entry.texture)
			PRBuffCheckMissing:SetChecked(entry.missing)
			PRBuffCheckDisabled:SetChecked(entry.disabled)
			PRColorSelect.normalTexture:SetVertexColor(unpack(entry.color))
		end

		frame:Show()
	end)		

	button5:SetScript("OnClick", function()
		local list

		if self.editMode == "Frames" then
			list = self.db.profile.headers
		elseif self.editMode == "Buffs" then
			list = self.db.profile.buffs
		end

		local idx = selected.idx
		local offset = FauxScrollFrame_GetOffset(scrollframe)

		local entry = list[offset + idx]
		table.remove(list, offset + idx)

		if self.editMode == "Frames" then
			local header = self.headers[offset + idx]
			header:Hide()
			header:SetAttribute("groupFilter", nil)
			header:SetAttribute("nameList", nil)
			self:CreateRaidHeaders()
		elseif self.editMode == "Buffs" then
			for unit in pairs(self.frames) do
				self:UNIT_AURA(nil, unit)
			end
		end

		selected = nil
		scrollframe.update()
	end)

	button6:SetScript("OnClick", function()
		if self.editMode == "Frames" then
			self.editMode = "Buffs"
			button6.text:SetText("Edit Frames")
			selected = nil
		elseif self.editMode == "Buffs" then
			self.editMode = "Frames"
			button6.text:SetText("Edit Buffs")
			selected = nil
		end
		scrollframe.update()
	end)

	self:CreateBuffEditWindow()
end

function PerfectRaid:CreateBuffEditWindow()
	local frame = CreateFrame("Frame", "PREditBuff")
	frame:SetFrameStrata("HIGH")
	frame:SetHeight(415)
	frame:SetWidth(350)
	frame:SetPoint("CENTER", 75, -25)
	self:SkinFrame(frame)
	frame.title:SetText("Edit Buff Notification")
	frame:Hide()

	local buffname = CreateFrame("EditBox", "PREditBuffName", frame, "InputBoxTemplate")
	buffname:SetPoint("TOPLEFT", 95, -35)
	buffname:SetWidth(200)
	buffname:SetHeight(25)
	buffname:SetAutoFocus(false)
	buffname.label = buffname:CreateFontString(nil, nil, "GameFontHighlightSmall")
	buffname.label:SetPoint("RIGHT", buffname, "LEFT", -10, 0)
	buffname.label:SetJustifyH("RIGHT")
	buffname.label:SetText("Buff Name:")

	local groupbuff = CreateFrame("EditBox", "PREditGroupName", frame, "InputBoxTemplate")
	groupbuff:SetPoint("TOPLEFT", buffname, "BOTTOMLEFT", 0, -5)
	groupbuff:SetWidth(200)
	groupbuff:SetHeight(25)
	groupbuff:SetAutoFocus(false)
	groupbuff.label = groupbuff:CreateFontString(nil, nil, "GameFontHighlightSmall")
	groupbuff.label:SetPoint("RIGHT", groupbuff, "LEFT", -10, 0)
	groupbuff.label:SetJustifyH("RIGHT")
	groupbuff.label:SetText("Group Name:")
	groupbuff:SetFrameStrata("DIALOG")

	local disptext = CreateFrame("EditBox", "PREditDispText", frame, "InputBoxTemplate")
	disptext:SetPoint("TOPLEFT", groupbuff, "BOTTOMLEFT", 0, -5)
	disptext:SetWidth(200)
	disptext:SetHeight(25)
	disptext:SetAutoFocus(false)
	disptext.label = disptext:CreateFontString(nil, nil, "GameFontHighlightSmall")
	disptext.label:SetPoint("RIGHT", disptext, "LEFT", -10, 0)
	disptext.label:SetJustifyH("RIGHT")
	disptext.label:SetText("Display Text:")

	-- Button for icon selection
	
	local iconbutton = CreateFrame("Button", "PRIconButton", frame)
	iconbutton.icon = iconbutton:CreateTexture(nil)
	iconbutton.icon:SetAllPoints()
	iconbutton.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
	iconbutton:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
	iconbutton:GetHighlightTexture():SetBlendMode("ADD")
	iconbutton:SetHeight(20)
	iconbutton:SetWidth(20)
	iconbutton:SetPoint("TOPLEFT", disptext, "BOTTOMLEFT", 0, -5)
	iconbutton.label = iconbutton:CreateFontString(nil, nil, "GameFontHighlightSmall")
	iconbutton.label:SetPoint("RIGHT", iconbutton, "LEFT", -10, 0)
	iconbutton.label:SetJustifyH("RIGHT")
	iconbutton.label:SetText("or icon:")

    local OnEnter = function()
        GameTooltip:SetOwner(button, "ANCHOR_TOPLEFT")
		GameTooltip:SetText("Click here to set icon")
        GameTooltip:Show()
    end
    
    iconbutton:SetScript("OnEnter", OnEnter)
    iconbutton:SetScript("OnLeave", function() GameTooltip:Hide() end)
	iconbutton:SetScript("OnClick", function() PRIconSelectFrame:Show() end)

	buffname:SetScript("OnTabPressed", function() 
		if IsShiftKeyDown() then disptext:SetFocus() else groupbuff:SetFocus() end
	end)
	groupbuff:SetScript("OnTabPressed", function()
		if IsShiftKeyDown() then buffname:SetFocus() else disptext:SetFocus() end
	end)
	disptext:SetScript("OnTabPressed", function() 
		if IsShiftKeyDown() then groupbuff:SetFocus() else buffname:SetFocus() end
	end)

	frame:SetScript("OnShow", function() buffname:SetFocus() end)

	-- Color Swatch
	local function colorSwatchCancel()
		local self = ColorPickerFrame.object;
		local r, g, b = self.r, self.g, self.b;
		self.normalTexture:SetVertexColor(r, g, b);
	end

	local function colorSwatchColor()
		local self = ColorPickerFrame.object;
		local r, g, b = ColorPickerFrame:GetColorRGB();
		self.normalTexture:SetVertexColor(r, g, b);
		self.color[1] = r
		self.color[2] = g
		self.color[3] = b
	end

	local function colorSwatchOpacity()
		local self = ColorPickerFrame.object;
		local a = OpacitySliderFrame:GetValue();
	end

	local function colorSwatchShow(self)
		local r, g, b, a;
		self.color = self.color or {1,1,1}

		local color = self.color;
		if ( color ) then
			r, g, b, a = unpack(color);
		end
		
		self.r, self.g, self.b = r, g, b
		self.opacityFunc = colorSwatchOpacity;
		self.swatchFunc = colorSwatchColor;
		self.cancelFunc = colorSwatchCancel;
		
		ColorPickerFrame.object = self;
		UIDropDownMenuButton_OpenColorPicker(self);
		ColorPickerFrame:SetFrameStrata("TOOLTIP");
		ColorPickerFrame:Raise();
	end

	local function colorSwatchOnClick(self)
		CloseMenus();
		colorSwatchShow(self);
	end

	local function colorSwatchOnEnter(self)
		self.bg:SetVertexColor(1, 0.82, 0);
	end

	local function colorSwatchOnLeave(self)
		self.bg:SetVertexColor(1, 1, 1);
	end

	local swatch = CreateFrame("Button", "PRColorSelect", frame);
	swatch:SetHeight(20) swatch:SetWidth(20)
	swatch:SetPoint("LEFT", disptext, "RIGHT", 5, 0)
	local bg = swatch:CreateTexture(nil, "BACKGROUND");
	local normalTexture = swatch:CreateTexture(nil, "ARTWORK");
	
	normalTexture:SetTexture("Interface\\ChatFrame\\ChatFrameColorSwatch");
	normalTexture:SetAllPoints(swatch);
	swatch:SetNormalTexture(normalTexture);
	bg:SetTexture(1, 1, 1);
	bg:SetPoint("TOPLEFT", swatch, 1, -1);
	bg:SetPoint("BOTTOMRIGHT", swatch, 0, 1);
	
	self.color = {1,1,1,1}
	if ( self.color ) then
		normalTexture:SetVertexColor(unpack(self.color))
	end
	
	swatch.bg, swatch.normalTexture = bg, normalTexture;
	swatch.object, swatch.hasAlpha = self, 1
	
	swatch:SetScript("OnLeave", colorSwatchOnLeave);
	swatch:SetScript("OnEnter", colorSwatchOnEnter);
	swatch:SetScript("OnClick", colorSwatchOnClick);

	function makecheck(text, func, name)
		name = name or text
		local box = CreateFrame("CheckButton", "PRBuffCheck"..name, frame, "UICheckButtonTemplate")
		box.text = getglobal(box:GetName().."Text")
		box.text:SetText(text)
		box.value = text
		box.func = func
		return box
	end
	
	-- Create buff condition checkboxes.
	local boxes = {}
	frame.boxes = boxes

	boxes[1] = makecheck("Warrior", self.conditions.Warrior)
	boxes[1]:SetPoint("TOPLEFT", iconbutton, "BOTTOMLEFT", -85, -5)
	boxes[2] = makecheck("Rogue", self.conditions.Rogue)
	boxes[2]:SetPoint("LEFT", boxes[1], "RIGHT", 80, 0)
	boxes[3] = makecheck("Paladin", self.conditions.Paladin)
	boxes[3]:SetPoint("LEFT", boxes[2], "RIGHT", 80, 0)

	boxes[4] = makecheck("Priest", self.conditions.Priest)
	boxes[4]:SetPoint("TOPLEFT", boxes[1], "BOTTOMLEFT", 0, -5)
	boxes[5] = makecheck("Shaman", self.conditions.Shaman)
	boxes[5]:SetPoint("LEFT", boxes[4], "RIGHT", 80, 0)
	boxes[6] = makecheck("Druid", self.conditions.Druid)
	boxes[6]:SetPoint("LEFT", boxes[5], "RIGHT", 80, 0)

	boxes[7] = makecheck("Hunter", self.conditions.Hunter)
	boxes[7]:SetPoint("TOPLEFT", boxes[4], "BOTTOMLEFT", 0, -5)
	boxes[8] = makecheck("Mage", self.conditions.Mage)
	boxes[8]:SetPoint("LEFT", boxes[7], "RIGHT", 80, 0)
	boxes[9] = makecheck("Warlock", self.conditions.Warlock)
	boxes[9]:SetPoint("LEFT", boxes[8], "RIGHT", 80, 0)

	boxes[10] = makecheck("All", self.conditions.All)
	boxes[10]:SetPoint("TOPLEFT", boxes[7], "BOTTOMLEFT", 0, -5)
	boxes[11] = makecheck("Melee", self.conditions.Melee)
	boxes[11]:SetPoint("LEFT", boxes[10], "RIGHT", 80, 0)
	boxes[12] = makecheck("Range", self.conditions.Range)
	boxes[12]:SetPoint("LEFT", boxes[11], "RIGHT", 80, 0)

	local missing = makecheck("Only display if the given buff is missing", nil, "Missing")
	missing:SetPoint("TOPLEFT", boxes[10], "BOTTOMLEFT", 0, -5)

	local disabled = makecheck("Disable", nil, "Disabled")
	disabled:SetPoint("TOPLEFT", missing, "BOTTOMLEFT", 0, -5)

	local saveicon = CreateFrame("Button", "PRButtonBuffSave", frame)
	self:SkinButton(saveicon)
	saveicon.text:SetText("Save")
	saveicon:SetPoint("CENTER", frame, "BOTTOM", -40, 25)

	local cancelicon = CreateFrame("Button", "PRButtonBuffCancel", frame)
	self:SkinButton(cancelicon)
	cancelicon.text:SetText("Cancel")
	cancelicon:SetPoint("CENTER", frame, "BOTTOM", 40, 25)

	-- Macro Frame
	-- Create the macro icon frame

	local macroframe = CreateFrame("Frame", "PRIconSelectFrame", frame)
	macroframe:SetWidth(296)
	macroframe:SetHeight(265)
	macroframe:SetPoint("CENTER",0,0)
	self:SkinFrame(macroframe)
	macroframe:SetFrameStrata("DIALOG")
	macroframe.title:SetText("Select an icon")
	macroframe:Hide()

	CreateFrame("CheckButton", "PRIcon1", macroframe, "PRaidIconTemplate")
	PRIcon1:SetID(1)
	PRIcon1:SetPoint("TOPLEFT", 25, -35)

	CreateFrame("CheckButton", "PRIcon2", macroframe, "PRaidIconTemplate")
	PRIcon2:SetID(2)
	PRIcon2:SetPoint("LEFT", PRIcon1, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon3", macroframe, "PRaidIconTemplate")
	PRIcon3:SetID(3)
	PRIcon3:SetPoint("LEFT", PRIcon2, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon4", macroframe, "PRaidIconTemplate")
	PRIcon4:SetID(4)
	PRIcon4:SetPoint("LEFT", PRIcon3, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon5", macroframe, "PRaidIconTemplate")
	PRIcon5:SetID(5)
	PRIcon5:SetPoint("LEFT", PRIcon4, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon6", macroframe, "PRaidIconTemplate")
	PRIcon6:SetID(6)
	PRIcon6:SetPoint("TOPLEFT", PRIcon1, "BOTTOMLEFT", 0, -10)

	CreateFrame("CheckButton", "PRIcon7", macroframe, "PRaidIconTemplate")
	PRIcon7:SetID(7)
	PRIcon7:SetPoint("LEFT", PRIcon6, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon8", macroframe, "PRaidIconTemplate")
	PRIcon8:SetID(8)
	PRIcon8:SetPoint("LEFT", PRIcon7, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon9", macroframe, "PRaidIconTemplate")
	PRIcon9:SetID(9)
	PRIcon9:SetPoint("LEFT", PRIcon8, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon10", macroframe, "PRaidIconTemplate")
	PRIcon10:SetID(10)
	PRIcon10:SetPoint("LEFT", PRIcon9, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon11", macroframe, "PRaidIconTemplate")
	PRIcon11:SetID(11)
	PRIcon11:SetPoint("TOPLEFT", PRIcon6, "BOTTOMLEFT", 0, -10)

	CreateFrame("CheckButton", "PRIcon12", macroframe, "PRaidIconTemplate")
	PRIcon12:SetID(12)
	PRIcon12:SetPoint("LEFT", PRIcon11, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon13", macroframe, "PRaidIconTemplate")
	PRIcon13:SetID(13)
	PRIcon13:SetPoint("LEFT", PRIcon12, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon14", macroframe, "PRaidIconTemplate")
	PRIcon14:SetID(14)
	PRIcon14:SetPoint("LEFT", PRIcon13, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon15", macroframe, "PRaidIconTemplate")
	PRIcon15:SetID(15)
	PRIcon15:SetPoint("LEFT", PRIcon14, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon16", macroframe, "PRaidIconTemplate")
	PRIcon16:SetID(16)
	PRIcon16:SetPoint("TOPLEFT", PRIcon11, "BOTTOMLEFT", 0, -10)

	CreateFrame("CheckButton", "PRIcon17", macroframe, "PRaidIconTemplate")
	PRIcon17:SetID(17)
	PRIcon17:SetPoint("LEFT", PRIcon16, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon18", macroframe, "PRaidIconTemplate")
	PRIcon18:SetID(18)
	PRIcon18:SetPoint("LEFT", PRIcon17, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon19", macroframe, "PRaidIconTemplate")
	PRIcon19:SetID(19)
	PRIcon19:SetPoint("LEFT", PRIcon18, "RIGHT", 10, 0)

	CreateFrame("CheckButton", "PRIcon20", macroframe, "PRaidIconTemplate")
	PRIcon20:SetID(20)
	PRIcon20:SetPoint("LEFT", PRIcon19, "RIGHT", 10, 0)

	local scrollframe = CreateFrame("ScrollFrame", "PRIconScrollFrame", macroframe, "FauxScrollFrameTemplate")
	scrollframe:SetPoint("TOPLEFT", PRIcon1, "TOPLEFT", 0, 0)
	scrollframe:SetPoint("BOTTOMRIGHT", PRIcon20, "BOTTOMRIGHT", 10, 0)

	local texture = scrollframe:CreateTexture(nil, "BACKGROUND")
	texture:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
	texture:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 14, 0)
	texture:SetPoint("BOTTOMRIGHT", 23, 0)
	texture:SetVertexColor(0.3, 0.3, 0.3)

	local texture = scrollframe:CreateTexture(nil, "BACKGROUND")
	texture:SetTexture("Interface\\ChatFrame\\ChatFrameBackground")
	texture:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, 0)
	texture:SetPoint("BOTTOMRIGHT", 14,0)
	texture:SetVertexColor(0.3, 0.3, 0.3)

	scrollframe:SetScript("OnVerticalScroll", function()
		local MACRO_ICON_ROW_HEIGHT = 36
		FauxScrollFrame_OnVerticalScroll(MACRO_ICON_ROW_HEIGHT, function() self:UpdateIconFrame() end)
	end)

	macroframe:SetScript("OnShow", function() self:UpdateIconFrame() end)

	local saveicon = CreateFrame("Button", "PRButtonIconSave", macroframe)
	self:SkinButton(saveicon)
	saveicon.text:SetText("Save")
	saveicon:SetPoint("CENTER", macroframe, "BOTTOM", -40, 25)

	local cancelicon = CreateFrame("Button", "PRButtonIconCancel", macroframe)
	self:SkinButton(cancelicon)
	cancelicon.text:SetText("Cancel")
	cancelicon:SetPoint("CENTER", macroframe, "BOTTOM", 40, 25)

	PRButtonBuffSave:SetScript("OnClick", function()
		local list = self.db.profile.buffs
		local entry = self.editSave or {}
		
		entry.name = buffname:GetText()
		entry.desc = disptext:GetText() or iconbutton.icon:GetTexture()
		entry.cond = {}
		for i,box in ipairs(boxes) do
			if box:GetChecked() then
				table.insert(entry.cond, box.value)
			end
		end
		entry.buffname = buffname:GetText()
		entry.groupbuff = groupbuff:GetText()
		entry.disptext = disptext:GetText()
		entry.texture = iconbutton.icon:GetTexture()
		entry.missing = missing:GetChecked()
		entry.disabled = disabled:GetChecked()
		entry.color = swatch.color
		entry.colortext = string.format("|cFF%s%s|r", utils.RGBToHex(unpack(entry.color)), entry.disptext)

		if not self.editSave then
			table.insert(list, entry)
		end
		PRButtonBuffCancel:Click()
		PRScrollFrame.update()
		for unit in pairs(self.frames) do
			self:UNIT_AURA("UNIT_AURA", unit)
		end
	end)

	PRButtonBuffCancel:SetScript("OnClick", function()
		PREditBuff:Hide()
		for k,v in ipairs(boxes) do
			v:SetChecked(nil)
			buffname:SetText("")
			groupbuff:SetText("")
			disptext:SetText("")
			iconbutton.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
			swatch.normalTexture:SetVertexColor(1,1,1)
		end
		missing:SetChecked(false)
	end)
end

function PerfectRaid:SelectBuffIcon()
	local texture = this.icon:GetTexture()
	PRIconButton.icon:SetTexture(texture)
	PRIconSelectFrame:Hide()
end

function PerfectRaid:UpdateIconFrame()
    local MAX_MACROS = 18;
    local NUM_MACRO_ICONS_SHOWN = 20;
    local NUM_ICONS_PER_ROW = 5;
    local NUM_ICON_ROWS = 4;
    local MACRO_ICON_ROW_HEIGHT = 36;
    local macroPopupOffset = FauxScrollFrame_GetOffset(PRIconScrollFrame);
    local numMacroIcons = GetNumMacroIcons();

    -- Icon list
    for i=1, NUM_MACRO_ICONS_SHOWN do
        macroPopupIcon = getglobal("PRIcon"..i.."Icon");
        macroPopupButton = getglobal("PRIcon"..i);
        
        if not macroPopupButton.icon then
            macroPopupButton.icon = macroPopupIcon
        end
        
        index = (macroPopupOffset * NUM_ICONS_PER_ROW) + i;
        if ( index <= numMacroIcons ) then
            macroPopupIcon:SetTexture(GetMacroIconInfo(index));
            macroPopupButton:Show();
        else
            macroPopupIcon:SetTexture("");
            macroPopupButton:Hide();
        end
        macroPopupButton:SetChecked(nil);
    end
    
    FauxScrollFrame_Update(PRIconScrollFrame, ceil(numMacroIcons / NUM_ICONS_PER_ROW) , NUM_ICON_ROWS, MACRO_ICON_ROW_HEIGHT );
end

PerfectRaid.conditions = {
	Warrior = function(u)
		local _,class = UnitClass(u)
		return class == "WARRIOR"
	end,
	Rogue = function(u)
		local _,class = UnitClass(u)
		return class == "ROGUE"
	end,
	Paladin = function(u)
		local _,class = UnitClass(u)
		return class == "PALADIN"
	end,
	Priest = function(u)
		local _,class = UnitClass(u)
		return class == "PRIEST"
	end,
	Shaman = function(u)
		local _,class = UnitClass(u)
		return class == "SHAMAN"
	end,
	Druid = function(u)
		local _,class = UnitClass(u)
		return class == "DRUID"
	end,
	Warlock = function(u)
		local _,class = UnitClass(u)
		return class == "WARLOCKS"
	end,
	Mage = function(u)
		local _,class = UnitClass(u)
		return class == "MAGE"
	end,
	Hunter = function(u)
		local _,class = UnitClass(u)
		return class == "HUNTER"
	end,
	All = function(u)
		return true
	end,
	Melee = function(u)
		local _,class = UnitClass(u)
		return class == "WARRIOR" or class == "ROGUE" or class == "PALADIN"
	end,
	Range = function(u)
		local _,class = UnitClass(u)
		return class == "PRIEST" or class == "WARLOCK" or class == "DRUID" or class == "MAGE" or class == "HUNTER" or class == "SHAMAN"
	end,
}
